﻿using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;
using WMSSystem.DYB;
using WMSSystem.WYJ;
using WMSSystem.YJ;
using WMSSystem.YSL.Dto.工作台.商品工作台;
using WMSSystem.YSL.Interfance;

namespace WMSSystem.YSL
{
    /// <summary>
    /// 工作台商品统计服务实现类
    /// </summary>
    public class GZTotalStatisticsService : ApplicationService, IGZTotalStatisticsService
    {
        private readonly IRepository<WYJ_SalesOrder, Guid> _salesOrderRepository;
        private readonly IRepository<WYJ_GoodsforSale, Guid> _goodsforSaleRepository;
        private readonly IRepository<Inboundmanagement, Guid> _inboundmanagementRepository;
        private readonly IRepository<WarehouseManagement, Guid> _warehouseManagementRepository;
        private readonly IRepository<Commoditiestable, Guid> _commoditiestableRepository;
        private readonly ILogger<GZTotalStatisticsService> _logger;

        public GZTotalStatisticsService(
            IRepository<WYJ_SalesOrder, Guid> salesOrderRepository,
            IRepository<WYJ_GoodsforSale, Guid> goodsforSaleRepository,
            IRepository<Inboundmanagement, Guid> inboundmanagementRepository,
            IRepository<WarehouseManagement, Guid> warehouseManagementRepository,
            IRepository<Commoditiestable, Guid> commoditiestableRepository,
            ILogger<GZTotalStatisticsService> logger)
        {
            _salesOrderRepository = salesOrderRepository;
            _goodsforSaleRepository = goodsforSaleRepository;
            _inboundmanagementRepository = inboundmanagementRepository;
            _warehouseManagementRepository = warehouseManagementRepository;
            _commoditiestableRepository = commoditiestableRepository;
            _logger = logger;
        }

        /// <summary>
        /// 统一统计方法 - 支持年、月、日统计
        /// </summary>
        /// <param name="year">年份（必填）</param>
        /// <param name="month">月份（可选，0表示年度统计）</param>
        /// <param name="day">日期（可选，0表示月度统计）</param>
        /// <returns>统计数据</returns>
        [UnitOfWork]
        public async Task<GZTotalMonthlySalesStatisticsDto> GetStatisticsAsync(int year, int month = 0, int day = 0)
        {
            try
            {
                // 参数验证
                ValidateStatisticsParameters(year, month, day);

                _logger.LogInformation("开始获取统计数据，参数：Year={Year}, Month={Month}, Day={Day}", year, month, day);

                // 确定统计类型
                var statisticsType = DetermineStatisticsType(month, day);

                // 构建时间过滤条件
                var dateFilter = BuildDateFilter(year, month, day);

                // 顺序执行统计查询以避免DbContext并发问题
                var totalSalesNums = await GetTotalSalesStatisticsAsync(dateFilter);
                var totalInput = await GetTotalInputStatisticsAsync(dateFilter);
                var totalSalesAmount = await GetTotalSalesAmountAsync(dateFilter);
                var warehouseCount = await GetWarehouseCountAsync();
                var currentInventory = await GetCurrentInventoryAsync();

                var result = new GZTotalMonthlySalesStatisticsDto
                {
                    Year = year,
                    Month = month,
                    TotalSalesNums = totalSalesNums,
                    TotalInput = totalInput,
                    TotalSalesAmount = totalSalesAmount,
                    WarehouseCount = warehouseCount,
                    CurrentInventory = currentInventory,
                    UpdateTime = DateTime.Now
                };

                _logger.LogInformation("统计数据获取成功，类型：{StatisticsType}，结果：TotalSalesNums={TotalSalesNums}, TotalInput={TotalInput}, TotalSalesAmount={TotalSalesAmount}, WarehouseCount={WarehouseCount}",
                    statisticsType, result.TotalSalesNums, result.TotalInput, result.TotalSalesAmount, result.WarehouseCount);

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取统计数据时发生错误，参数：Year={Year}, Month={Month}, Day={Day}", year, month, day);
                throw new UserFriendlyException("获取统计数据失败，请稍后重试", ex.Message);
            }
        }
        /// <summary>
        /// 验证统计参数
        /// </summary>
        private void ValidateStatisticsParameters(int year, int month, int day)
        {
            var currentYear = DateTime.Now.Year;

            if (year < 1900 || year > currentYear + 1)
            {
                throw new UserFriendlyException($"年份参数无效，必须在1900到{currentYear + 1}之间");
            }

            if (month < 0 || month > 12)
            {
                throw new UserFriendlyException("月份参数无效，必须在0到12之间（0表示年度统计）");
            }

            if (day < 0 || day > 31)
            {
                throw new UserFriendlyException("日期参数无效，必须在0到31之间（0表示月度统计）");
            }

            // 验证日期组合的有效性
            if (month > 0 && day > 0)
            {
                try
                {
                    var testDate = new DateTime(year, month, day);
                }
                catch (ArgumentOutOfRangeException)
                {
                    throw new UserFriendlyException($"无效的日期组合：{year}-{month}-{day}");
                }
            }
        }

        /// <summary>
        /// 确定统计类型
        /// </summary>
        private string DetermineStatisticsType(int month, int day)
        {
            if (month == 0)
                return "年度统计";
            else if (day == 0)
                return "月度统计";
            else
                return "日度统计";
        }

        /// <summary>
        /// 构建日期过滤条件
        /// </summary>
        private DateFilter BuildDateFilter(int year, int month, int day)
        {
            return new DateFilter
            {
                Year = year,
                Month = month,
                Day = day,
                IsYearlyStatistics = month == 0,
                IsMonthlyStatistics = month > 0 && day == 0,
                IsDailyStatistics = month > 0 && day > 0
            };
        }

        /// <summary>
        /// 获取总销售数量
        /// </summary>
        private async Task<int> GetTotalSalesStatisticsAsync(DateFilter dateFilter)
        {
            try
            {
                var query = await _goodsforSaleRepository.GetQueryableAsync();
                var filteredQuery = ApplyDateFilter(query, dateFilter);

                var totalSales = await AsyncExecuter.CountAsync(filteredQuery);
                return totalSales;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取总销售数量时发生错误");
                return 0;
            }
        }

        /// <summary>
        /// 获取总入库数量
        /// </summary>
        private async Task<int> GetTotalInputStatisticsAsync(DateFilter dateFilter)
        {
            try
            {
                var query = await _inboundmanagementRepository.GetQueryableAsync();
                var filteredQuery = ApplyDateFilter(query, dateFilter);

                // 只统计已完成的入库记录
                var totalInput = await AsyncExecuter.SumAsync(filteredQuery.Where(x => x.State == 4), x => x.Num ?? 0);
                return totalInput;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取总入库数量时发生错误");
                return 0;
            }
        }

        /// <summary>
        /// 获取总销售金额
        /// </summary>
        private async Task<decimal> GetTotalSalesAmountAsync(DateFilter dateFilter)
        {
            try
            {
                var query = await _salesOrderRepository.GetQueryableAsync();
                var filteredQuery = ApplyDateFilter(query, dateFilter);

                // 只统计已完成的销售订单
                var totalAmount = await AsyncExecuter.SumAsync(filteredQuery.Where(x => x.OrderStatus == "已完成"), x => x.OrderMoney ?? 0);
                return totalAmount;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取总销售金额时发生错误");
                return 0;
            }
        }

        /// <summary>
        /// 获取仓库总数
        /// </summary>
        private async Task<int> GetWarehouseCountAsync()
        {
            try
            {
                var query = await _warehouseManagementRepository.GetQueryableAsync();
                var warehouseCount = await AsyncExecuter.CountAsync(query.Where(x => x.State == true)); // 只统计启用状态的仓库
                return warehouseCount;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取仓库总数时发生错误");
                return 0;
            }
        }

        /// <summary>
        /// 获取当前库存信息
        /// </summary>
        private async Task<string> GetCurrentInventoryAsync()
        {
            try
            {
                var query = await _commoditiestableRepository.GetQueryableAsync();
                var totalCommodities = await AsyncExecuter.CountAsync(query);
                return $"当前共有 {totalCommodities} 种商品";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取当前库存信息时发生错误");
                return "库存信息获取失败";
            }
        }

        /// <summary>
        /// 应用日期过滤条件
        /// </summary>
        private IQueryable<T> ApplyDateFilter<T>(IQueryable<T> query, DateFilter dateFilter)
        {
            if (typeof(T) == typeof(WYJ_GoodsforSale))
            {
                var typedQuery = query as IQueryable<WYJ_GoodsforSale>;
                typedQuery = typedQuery.Where(x => x.CreationTime.Year == dateFilter.Year);

                if (dateFilter.Month > 0)
                {
                    typedQuery = typedQuery.Where(x => x.CreationTime.Month == dateFilter.Month);

                    if (dateFilter.Day > 0)
                    {
                        typedQuery = typedQuery.Where(x => x.CreationTime.Day == dateFilter.Day);
                    }
                }
                return typedQuery as IQueryable<T>;
            }
            else if (typeof(T) == typeof(Inboundmanagement))
            {
                var typedQuery = query as IQueryable<Inboundmanagement>;
                typedQuery = typedQuery.Where(x => x.Date.Year == dateFilter.Year);

                if (dateFilter.Month > 0)
                {
                    typedQuery = typedQuery.Where(x => x.Date.Month == dateFilter.Month);

                    if (dateFilter.Day > 0)
                    {
                        typedQuery = typedQuery.Where(x => x.Date.Day == dateFilter.Day);
                    }
                }
                return typedQuery as IQueryable<T>;
            }
            else if (typeof(T) == typeof(WYJ_SalesOrder))
            {
                var typedQuery = query as IQueryable<WYJ_SalesOrder>;
                typedQuery = typedQuery.Where(x => x.CreationTime.Year == dateFilter.Year);

                if (dateFilter.Month > 0)
                {
                    typedQuery = typedQuery.Where(x => x.CreationTime.Month == dateFilter.Month);

                    if (dateFilter.Day > 0)
                    {
                        typedQuery = typedQuery.Where(x => x.CreationTime.Day == dateFilter.Day);
                    }
                }
                return typedQuery as IQueryable<T>;
            }

            return query;
        }

        /// <summary>
        /// 获取综合统计数据（包含总销售数量、总入库数量、总销售金额、仓库总数）
        /// </summary>
        /// <param name="year">年份（可选）</param>
        /// <param name="month">月份（可选）</param>
        /// <param name="day">日期（可选）</param>
        /// <returns>综合统计数据</returns>
        [UnitOfWork]
        public async Task<GZTotalMonthlySalesStatisticsDto> GetComprehensiveStatisticsAsync(int? year = null, int? month = null, int? day = null)
        {
            try
            {
                // 如果没有指定年份，使用当前年份
                var targetYear = year ?? DateTime.Now.Year;
                var targetMonth = month ?? 0;
                var targetDay = day ?? 0;

                return await GetStatisticsAsync(targetYear, targetMonth, targetDay);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取综合统计数据时发生错误");
                throw new UserFriendlyException("获取综合统计数据失败，请稍后重试", ex.Message);
            }
        }

        /// <summary>
        /// 获取实时统计数据
        /// </summary>
        public async Task<GZTotalGetRealTimeStatisticsOutputDto> GetRealTimeStatisticsAsync(GZTotalGetRealTimeStatisticsInputDto input)
        {
            try
            {
                var year = input.Year ?? DateTime.Now.Year;
                var month = input.Month ?? 0;
                var day = input.Day ?? 0;

                var comprehensiveStats = await GetStatisticsAsync(year, month, day);

                return new GZTotalGetRealTimeStatisticsOutputDto
                {
                    MonthlyStatistics = new List<GZTotalMonthlySalesStatisticsDto> { comprehensiveStats },
                    TotalStatistics = comprehensiveStats,
                    LastUpdateTime = DateTime.Now
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取实时统计数据时发生错误");
                throw new UserFriendlyException("获取实时统计数据失败", ex.Message);
            }
        }

        /// <summary>
        /// 获取工作台概览数据
        /// </summary>
        public async Task<GZTotalGetRealTimeStatisticsOutputDto> GetWorkbenchOverviewAsync()
        {
            try
            {
                return await GetRealTimeStatisticsAsync(new GZTotalGetRealTimeStatisticsInputDto());
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取工作台概览数据时发生错误");
                throw new UserFriendlyException("获取工作台概览数据失败", ex.Message);
            }
        }
    }

   
}